package com.haike.pushjobs.jobs;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.csv.CsvData;
import cn.hutool.core.text.csv.CsvReadConfig;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.ftp.Ftp;
import cn.hutool.extra.ftp.FtpConfig;
import cn.hutool.extra.ftp.FtpMode;
import cn.hutool.json.JSONUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.haike.pushjobs.config.GAOLANGANFtpConfig;
import com.haike.pushjobs.service.TPushRecordService;
import com.haike.pushjobs.utils.CSVUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.ibatis.session.SqlSession;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.regex.Pattern;


/**
 * 预报增水（从ftp上CSV文件）
 * /GFS+WRF+ADCIRC+SWAN/data_GaoLanGang/theaty_station_data_6003_2025092917.csv文件: 增水预报数据
 */
@Slf4j
@DisallowConcurrentExecution
@Component
public class Download_theaty_station_data_Job implements Job {

    @Autowired
    SqlSession daoSession;

    @Autowired
    TPushRecordService pushRecordService;

    @Autowired
    private GAOLANGANFtpConfig GAOLANGANFtpConfig;
    String description = "";

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        long funStartTime = System.currentTimeMillis();
        description = context.getJobDetail().getDescription();
        try {
            String param = context.getMergedJobDataMap().getString("param");
            log.info(description + "开始 - 参数: {}", param);

            Map<String, Object> paramMap = JSONUtil.toBean(param, Map.class);

            runTask(paramMap);

        } catch (Exception e) {
            log.error(description + "执行出错", e);
        } finally {
            log.info(description + "执行完成: {} 毫秒", System.currentTimeMillis() - funStartTime);
            log.info("[{}]清除数据源上下文", description);
            DynamicDataSourceContextHolder.clear();
        }
    }


    //region 执行任务

    /**
     * 执行任务
     *
     * @param paramMap
     */
    public void runTask(Map<String, Object> paramMap) {
        String currentDate = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        var is_replace = MapUtil.getBool(paramMap, "is_replace", false);

        // FTP服务器配置（使用提供的信息）
        String host = GAOLANGANFtpConfig.getHost();     // FTP服务器主机地址
        int port = GAOLANGANFtpConfig.getPort();        // 端口
        String username = GAOLANGANFtpConfig.getUsername(); // 用户名
        String password = GAOLANGANFtpConfig.getPassword(); // 密码

        String rootDir = "/GFS+WRF+ADCIRC+SWAN/data_GaoLanGang/";

        // 创建FTP连接配置
        FtpConfig config = new FtpConfig(host, port, username, password, Charset.defaultCharset());
        // 建立FTP连接
        try (Ftp ftp = new Ftp(config, FtpMode.Passive)) {

            var dirList = ftp.lsFiles(rootDir, file -> file.isDirectory());
            if (dirList.size() == 0) {
                log.info("无目录");
                return;
            }
            // dirList进行排序, 降序
            dirList.sort(Comparator.comparing(FTPFile::getName).reversed());


            for (int i = 0; i <= 1; i++) {
                // 只取最新的两个月目录
                FTPFile dir = dirList.get(i);
                // 获取文件名
                String dirName = dir.getName();
                log.info("[目录] " + dirName);

                String remoteDir = rootDir + dirName + "/";               // 要列出文件的远程目录，这里使用根目录
                String targetDir = remoteDir.substring(1);
                // 获取当前目录下的所有文件和文件夹列表, 只要.csv文件
                var fileList = ftp.lsFiles(remoteDir, file -> file.getName().endsWith(".csv"));

                log.info("目录 " + remoteDir + " 下的文件列表:");
                for (FTPFile file : fileList) {
                    try {
                        var fileName = file.getName();

                        // 检查文件最后修改时间，如果大于10小时,则跳过
                        var lastModified = DateUtil.parse(DateUtil.formatDateTime(file.getTimestamp().getTime()));
                        lastModified = DateUtil.offsetHour(lastModified, 8);
                        if (lastModified.before(DateUtil.offsetHour(new Date(), -10))) {
                            log.info("文件[{}]最后修改时间大于10小时，跳过处理", fileName);
                            continue;
                        }

                        // 文件名格式: theaty_station_data_6007_2025112011.csv, 解析出2025112011, 使用正则表达式
//                        var matcher = Pattern.compile("^theaty_station_data_(.*)_(.*).csv$").matcher(fileName);
//                        if (matcher.matches()) {
//                            log.info(matcher.group(1));
//                            log.info(matcher.group(2));
//                            Date fileDate = DateUtil.parse(matcher.group(2), "yyyyMMddHH");
//
//                            if (fileDate.before(DateUtil.offsetDay(new Date(), -2))) {
//                                log.info("超过2天的数据, 跳过");
//                                continue;
//                            }
//                        }

                        //region 下载文件
                        if (!FileUtil.exist(targetDir)) {
                            FileUtil.mkdir(targetDir);
                        }
                        String saveFilePath = targetDir + fileName;
                        log.info("保存文件: {}", saveFilePath);

                        if (!is_replace && FileUtil.exist(saveFilePath)) {
                            log.info("[跳过]文件已存在: {}", saveFilePath);
                            continue;
                        }
                        ftp.download(remoteDir + fileName, FileUtil.file(saveFilePath));
                        //endregion

                        //region 插入到数据库
                        var list = CSVUtils.parseCSV(saveFilePath);
                        for (var item : list) {
                            log.info("[{}]开始推送数据: {}", description, item);
                            item.put("id", IdUtil.getSnowflakeNextIdStr());
                            // 遍历item. 值为空字符串时, 设置为null
                            for (var entry : item.entrySet()) {
                                if (entry.getValue().toString().equals("")) {
                                    entry.setValue(null);
                                }
                            }
                            daoSession.insert("data.insert_theaty_station_data", item);
                        }
                        //endregion


                    } catch (Exception e) {
                        log.error("下载文件,解析,入库出错: {}", e.getMessage());
                    }
                }
            }


        } catch (Exception e) {
            log.error("FTP操作出错: " + e.getMessage(), e);
        }
    }
    //endregion


}